package ext.tianma.part.imported;


import java.lang.reflect.InvocationTargetException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

import wt.fc.PersistenceHelper;
import wt.method.RemoteAccess;
import wt.method.RemoteMethodServer;
import wt.part.LineNumber;
import wt.part.Quantity;
import wt.part.QuantityUnit;
import wt.part.WTPart;
import wt.part.WTPartMaster;
import wt.part.WTPartUsageLink;
import wt.session.SessionServerHelper;
import wt.util.WTException;
import ext.com.core.CoreUtil;
import ext.com.iba.IBAUtil;
import ext.com.workflow.WorkflowUtil;
import ext.tianma.part.MyPartUtil;

/**
 * BOM导入类
 * @author KWang
 *
 */

public class CusImportBOM implements RemoteAccess{
	private static final String CLASSNAME = CusImportBOM.class.getName();
	/**
	 * 导入BOM结构主入口
	 * @param excel
	 * @return
	 */
	public static StringBuffer importBoms( String excel ){
		
		StringBuffer logs = new StringBuffer("");
		Sheet sheet = ImportedExcelUtil.getFirstSheet( excel );
		
		if( sheet != null ){
			try {
				importBoms ( sheet ,logs);
			} catch (WTException e) {
				e.printStackTrace();
			}finally{
				System.out.println( "Debug   logs:"+logs.toString() ); 
			}
		}
		return logs;
	}

	private static void importBoms(Sheet sheet, StringBuffer logs) throws WTException {
		
		 Map< Integer, String> headMap = getHeader( sheet );
		 List< WTPart >   checkInPartList = new ArrayList< WTPart >();
		 Set< String >   errorPartList = new HashSet< String >();
		 Iterator<Row> rowIterator =  sheet.rowIterator();
		 
		 boolean flag = SessionServerHelper.manager.setAccessEnforced(false);
		 try {
			 while ( rowIterator.hasNext() ) {
				 
					Row row = rowIterator.next();
					if( row != null ){
						int rowNumber =  row.getRowNum();
						
						int rowNumberRow = rowNumber + 1 ;
						
						System.out.println( "Start Process Row "+ rowNumberRow);
						if( rowNumber > ImportConstants.BOM_HEADER_ROW_INDEX ){
							
							if( headMap != null ){
								importBoms( row , headMap ,logs ,checkInPartList,errorPartList);
							}						
						}
						System.out.println( "End Process Row "+ rowNumberRow);
					}	
				}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			System.out.println("errorPartList size : " + errorPartList.size());
			for (String string : errorPartList) {
				System.out.println("errorPartList partNumber : " + string);
			}
			checkinWTPart(checkInPartList);
			SessionServerHelper.manager.setAccessEnforced(flag);
		} 	
	}
	
	private static void importBoms(Row row, Map<Integer, String> headMap, StringBuffer logs , List< WTPart >   checkInPartList,Set< String >   errorPartList) {
		String parentNumber = "";
		String parentView = "";
		String parentVersion = "";
		String childNumber = "";
		String lineNumber = "";
		String quantity = "";
		String unit = "";
		WTPart parentPart = null;
		WTPartMaster childPartMaster = null; 
		
		
		Iterator<Cell> cellIterator =  row.cellIterator();
		Hashtable hashtable = new Hashtable();
		hashtable.clear();
		while( cellIterator.hasNext() ){
			
			Cell cell = cellIterator.next();
			if( cell != null ){
				int columnIndex =  cell.getColumnIndex();
				String head = headMap.get( columnIndex );
				if( head == null || head.trim().isEmpty() ){
					continue;
				}
				if( head.equals("Parent") ){
					parentNumber = ImportedExcelUtil.getCellValueAsString(cell,true).trim();
				}else if( head.equals("Revision") ){
					parentVersion = ImportedExcelUtil.getCellValueAsString(cell,true).trim();
				}else if( head.equals("View") ){
					parentView = ImportedExcelUtil.getCellValueAsString(cell).trim();
				}else if( head.equals("Child") ){
					childNumber = ImportedExcelUtil.getCellValueAsString(cell,true).trim();
				}else if( head.equals("Line Number") ){
					lineNumber = ImportedExcelUtil.getCellValueAsString(cell,true).trim();
				}else if( head.equals("Quantity") ){
					quantity = ImportedExcelUtil.getCellValueAsString(cell).trim();
				}else if( head.equals("Unit of Measure") ){
					unit = ImportedExcelUtil.getCellValueAsString(cell).trim();
				}else if(head.equals("Reference Designators")){
					
				}else if(head.equals("Trace Code")){
					
				}else if(head.equals("Find Number")){
					
				}else if(head.equals("Level")){
					
				}else if(head.equals("Action")){
					
				}else{
					String ibavalue = ImportedExcelUtil.getCellValueAsString(cell,true).trim();
					System.out.println( "Debug   head:"+head );
					if( ibavalue != null && head != null ){
						if( !head.trim().isEmpty() && !ibavalue.trim().isEmpty() ){
							hashtable.put(head, ibavalue);
						}
					}
				}
			}					
		}
		try {
			parentPart = getParentPart ( parentNumber,parentView ,parentVersion );
			childPartMaster = getChildPartMaster(childNumber);
			if(parentPart == null ){
				
				errorPartList.add(parentNumber);
			}
			if(childPartMaster == null){
				errorPartList.add(childNumber);
			}
			if( parentPart != null && childPartMaster !=null ){
				if( needCreateWTPartUsageLink(parentPart,childPartMaster,lineNumber) ){	
					
					if( !WorkflowUtil.isObjectCheckedOut( parentPart ) ){
						parentPart = (WTPart) CoreUtil.checkoutObject(parentPart);
					}
					
					if( !checkInPartList.contains(parentPart) ){
						checkInPartList.add(parentPart);
					}
								
					double quanty = Double.parseDouble(quantity);
					QuantityUnit qu = null;
					if( childPartMaster != null ){
						qu = childPartMaster.getDefaultUnit() ;
					}
					if( qu == null ){
						qu =  QuantityUnit.toQuantityUnit( unit );
					}
					if( qu != null ){
						Quantity qtity = Quantity.newQuantity( quanty , qu);
						createWTPartUsageLink( parentPart,childPartMaster,lineNumber, qtity ,hashtable);	
					}
				}			
			}else{
				System.out.println("ERROR 父件:" + parentNumber + "不存在,或者子件:" + childNumber + "不存在");
				//throw new WTException("ERROR 父件:" + parentNumber + "不存在,或者子件:" + childNumber + "不存在");
			}
		} catch (WTException e) {
			System.out.println( "ERROR parentPart," + parentPart.getNumber() + ";childPartMaster," + childPartMaster.getNumber());
			e.printStackTrace();
		}
		
	}
	
	/**
	 * 检入已检出的
	 * @param outPart
	 */
	private static void checkinWTPart( List<WTPart> outPart ){
		
		if( outPart != null ){
			for (int i = 0; i < outPart.size(); i++) {
				WTPart inPart = outPart.get( i );
				if( inPart != null ){
					try {
						CoreUtil.checkinObject(inPart, "导入BOM结构完成后，检入零部件。");
					} catch (WTException e) {
						e.printStackTrace();
					}
				}
			}
		}
		
	}
	
	/**
	 * 创建UsageLink方法
	 * @param parentPart
	 * @param childPartMaster
	 * @param lineNumber
	 * @param hashtable
	 * @throws WTException
	 */
	private static void createWTPartUsageLink(WTPart parentPart, WTPartMaster childPartMaster, String lineNumber, Quantity quantity , Hashtable hashtable) {
		if( parentPart == null ||  childPartMaster == null ){
			return;
		}
		WTPartUsageLink usageLink;
		try {
			usageLink = WTPartUsageLink.newWTPartUsageLink(parentPart, childPartMaster);
			//设置行号
			setLineNumber(lineNumber, usageLink);
			
			//设置单位数量
			setQuantity( quantity,usageLink );
			usageLink = (WTPartUsageLink) PersistenceHelper.manager.save( usageLink );
			System.out.println( "Debug   hashtable:"+hashtable.size() );
			IBAUtil.forceSetIBAValues(usageLink, hashtable);
		} catch (WTException e) {
			System.out.println( "ERROR  createWTPartUsageLink: parentPart," + parentPart.getNumber() + ";childPartMaster," + childPartMaster.getNumber());
			e.printStackTrace();
		}
		
	}
	
	
	/**
	 * 设置usageLink的单位数量
	 * @param quantity
	 * @param usageLink
	 */
	private static void setQuantity(Quantity quantity, WTPartUsageLink usageLink) {		
		if( quantity != null && !quantity.equals("") ){
			usageLink.setQuantity(quantity);
		}		
	}

	/**
	 * 创建一个usageLink关系对象并且为其行号复制
	 * @param lineNumber
	 * @param usageLink
	 * @throws WTException
	 */
	private static void setLineNumber(String lineNumber,WTPartUsageLink usageLink) throws WTException {
		if( lineNumber != null && !lineNumber.equals("") ){
			
			try {
				long lineNumberValue = Long.parseLong(lineNumber);
				LineNumber newLineNumber = LineNumber.newLineNumber(lineNumberValue);			
				usageLink.setLineNumber(newLineNumber);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 判断usageLink关系是否存在
	 * @param parentPart
	 * @param childPartMaster
	 * @param lineNumber
	 * @return
	 * @throws WTException
	 */
	private static boolean needCreateWTPartUsageLink(WTPart parentPart, WTPartMaster childPartMaster, String lineNumber) throws WTException {
		boolean result = true;
		
		if( parentPart == null || childPartMaster == null ){
			return result;
		}
		
		List<WTPartUsageLink> allLink = getAllPartUsageLink( parentPart , childPartMaster );
		Iterator<WTPartUsageLink> linkIterator = allLink.iterator();
		while ( linkIterator.hasNext() ) {
			WTPartUsageLink usageLink = linkIterator.next();
			String uLinNumber = getLineNumber( usageLink );
			if( uLinNumber.equals(lineNumber) ){
				result = false;
				break;
			}		
		}
		
		return result;
	}
	
	/**
	 * 获取usageLink的number
	 * @param usageLink
	 * @return
	 */
	private static String getLineNumber(WTPartUsageLink usageLink) {
		String lineNumber =  "";
		
		if( usageLink == null ){
			return lineNumber;
		}
		LineNumber pLineNumber =  usageLink.getLineNumber();
		if( pLineNumber != null ){
			lineNumber = pLineNumber.getValue() + "";			 
		}
		
		return lineNumber;
	}
	
	/**
	 * 获取指定父件与子件Master所有的usageLink关系对象
	 * @param parentPart
	 * @param childPartMaster
	 * @return
	 * @throws WTException
	 */
	private static List<WTPartUsageLink> getAllPartUsageLink(WTPart parentPart, WTPartMaster childPartMaster) throws WTException {
		List<WTPartUsageLink> childPartUsageLinkList = new ArrayList<WTPartUsageLink>();
		
		List<WTPartUsageLink> allUsageLinkList = MyPartUtil.getFirstLevelUsageLink(parentPart);
		
		Iterator<WTPartUsageLink> allLinkIterator = allUsageLinkList.iterator();
		while( allLinkIterator.hasNext() ){
			WTPartUsageLink partUsageLink = allLinkIterator.next();
			WTPartMaster master =  partUsageLink.getUses();
			if( PersistenceHelper.isEquivalent(master, childPartMaster) ){
				childPartUsageLinkList.add(partUsageLink);
			}
		}	
		
		return childPartUsageLinkList;
	}
	
	/**
	 * 根据编号获取WTPartMaster
	 * @param childNumber
	 * @return
	 * @throws WTException
	 */
	private static WTPartMaster getChildPartMaster(String childNumber) throws WTException {
		
		return MyPartUtil.getWTPartMasterByNumber(childNumber);
	}
	
	/**
	 * 根据视图,编号,版本(指定大版本)获取相应对象
	 * @param parentNumber
	 * @param parentView
	 * @param parentVersion
	 * @return
	 */
	private static WTPart getParentPart(String parentNumber, String parentView,String parentVersion) {
		WTPart parentPart = null;
		try {
			
			if( !parentVersion.equals("") ){
				parentPart = MyPartUtil.getWTPartByNumViewAndVersion(parentNumber, parentView, parentVersion);
				if( parentPart == null ){
					parentPart = CoreUtil.getWTPartByNumberAndView( parentNumber , parentView );
				}
				
			}else if( parentVersion.equals("") ){
				parentPart = CoreUtil.getWTPartByNumberAndView( parentNumber , parentView );			}
			
		} catch (WTException e) {
			e.printStackTrace();
		}
			
		return parentPart;
	}
	
	/**
	 * 获取excel表头
	 * @param sheet
	 * @return
	 */
	private static Map<Integer, String> getHeader(Sheet sheet) {
		
		Map<Integer, String> headerMap = new HashMap<Integer, String>();
		
		Row row =  sheet.getRow(ImportConstants.BOM_HEADER_ROW_INDEX);
		
		if( row != null ){
			Iterator<Cell> iterator =   row.cellIterator();
			while ( iterator.hasNext() ) {
				Cell cell = iterator.next();
				
				String header = ImportedExcelUtil.getCellValueAsString(cell).trim();
				Integer columnIndex =  cell.getColumnIndex();
				if( header != null &&  !header.trim().isEmpty() ){
					headerMap.put(columnIndex, header);
				}				
			}			
		}
					
		return headerMap;
	} 
	
	public static void main(String[] args) {
		
		if( args == null || args.length != 1 ){
			return;
		}
		
		if (!RemoteMethodServer.ServerFlag) {
			String method = "importBoms";			
		
				try {
					System.out.println( "Debug   RemoteMethodServer..." );
					RemoteMethodServer.getDefault().invoke(method, CLASSNAME, null,
							new Class[] { String.class }, new Object[] { args[0] });
					System.out.println( "Debug  end RemoteMethodServer..." );
				} catch (RemoteException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			
		}else{
			System.out.println( "Debug   importBoms..." );
			importBoms( args[0] ) ;
			System.out.println( "Debug   end importBoms..." );
		}
	}
}
